#pragma once

#include "ThreadCache.h"
#include "PageCache.h"
#include <thread>

static void* ConcurrentAlloc(size_t size)
{
	if (size > MAX_SIZE)
	{
		size_t alignsize = SizeClass::RoundUp(size);
		size_t k = alignsize >> PAGE_SHIFT;

		PageCache::GetPageSingtelon()->GetPageMutex().lock();
		Span* span = PageCache::GetPageSingtelon()->NewSpan(k);
		span->_alignsize = alignsize;
		PageCache::GetPageSingtelon()->GetPageMutex().unlock();

		return (void*)(span->_page_id << PAGE_SHIFT);
	}

	//static ObjectPool<ThreadCache> _pool;
	if (pThreadCache == nullptr)
	{
		static ObjectPool<ThreadCache> _pool;
		//pThreadCache = new ThreadCache;
		pThreadCache = _pool.New();
	}

	//std::cout << std::this_thread::get_id() << "->";
	//std::cout << pThreadCache << std::endl;

	return pThreadCache->Allocate(size);
}

static void ConcurrentFree(void* ptr)
{
	Span* span = PageCache::GetPageSingtelon()->IdToSpan(ptr);
	size_t size = span->_alignsize;

	if (size > MAX_SIZE)
	{
		PageCache::GetPageSingtelon()->GetPageMutex().lock();
		PageCache::GetPageSingtelon()->ReleaseSpanToPageCache(span);
		PageCache::GetPageSingtelon()->GetPageMutex().unlock();
		return;
	}

	assert(pThreadCache);

	pThreadCache->Deallocate(ptr, size);
}